home *** CD-ROM | disk | FTP | other *** search
/ PC Format (UK) 124 / pcfcd124-a.iso / Trial Software / BlitzBasic / Rift2001-05-16 / Rift2 / tutorial2d-complete.bb < prev   
Encoding:
Text File  |  2001-05-16  |  46.7 KB  |  891 lines

  1. AppTitle "Celestial Rift - Version 1.1 (C)2001 Myke P" ;what this program will be called in MICROSOFT WINDOWS.
  2.  
  3. ;This makes two CONSTants. These are values which will NOT change at any point in the program, so we set their values now.
  4. Const SCREEN_WIDTH = 800
  5. Const SCREEN_HEIGHT = 600
  6. ;This is the code which tells Blitz what Display Resolution to use on the Graphics Card. The "GRAPHICS" command should always be placed before you do
  7. ;*anything* image-related in your program
  8. Graphics SCREEN_WIDTH,SCREEN_HEIGHT,0,1    ;start the graphics mode at SCREEN_WIDTH by SCREEN_HEIGHT, let Blitz choose the depth (,0) and run full screen (,1)
  9.  
  10. ;more program CONSTants..
  11. Const GAME_AREA_X = 50000    ;these two set the size of the map. You *should* keep them the same, 'cos the radar is square
  12. Const GAME_AREA_Y = 50000    ;but technically, you can change the values to anything you like! ;)
  13. ;the following constants are keyboard "SCAN" codes. Every key on the keyboard has a number. You can get the full list in your Blitz manual.
  14. Const KEY_CLOCKWISE = 25    ;(p)    
  15. Const KEY_ANTICWISE = 24    ;(o)
  16. Const KEY_SPEEDUP = 16        ;(q)
  17. Const KEY_SPEEDDOWN = 30    ;(a)
  18. Const KEY_FIRE = 57            ;(Space)
  19. Const KEY_HYPER = 2            ;(1)
  20. Const KEY_BOOST = 50        ;(m)
  21. Const KEY_CLOAK = 46        ;(c)
  22. Const KEY_QUIT = 1            ;(Escape)
  23. Const KEY_PAUSE = 7            ;(Number 6 on the main keyboard)
  24. Const KEY_DEBUG = 59        ;(F1)
  25. Const KEY_SAVESCREEN = 88    ;(F12)
  26. ;the following constants affect the way the game plays. Feel free to mess with the values..
  27. Const INCR_ROTATE# = 5                ;.. but DON'T touch this, otherwise the game will crash (I only drew the animation frames for 5 degree intervals!)
  28. Const INCR_SPEED# = 0.5
  29. Const INCR_SLOW# = 0.125
  30. Const INCR_BOOSTERS_UP# = 0.025
  31. Const INCR_BOOSTERS_DOWN# = .75
  32. Const INCR_CLOAK_UP#= 0.0125
  33. Const INCR_CLOAK_DOWN# = .25 
  34. Const SPEED_MAX = 25
  35. Const SPEED_MIN = -5
  36.  
  37. ;set up changable variables for game/menu (with initial values, if you like - i.e.: you could just as soon as set them later!)
  38. Global FLAG_GAMEON
  39. Global FLAG_MENUON
  40. Global FLAG_PAUSE
  41. Global FLAG_SAVESCREEN = 0
  42. Global FLAG_DEBUG = 0
  43. Global FLAG_GAMESTARTER
  44. Global PLAYER_SHIELD#
  45. Global PLAYER_BOOSTERS#
  46. Global PLAYER_CLOAK#
  47. Global PLAYER_JUMPS
  48. Global PLAYER_SPEED#
  49. Global PLAYER_ANGLE#
  50. Global PLAYER_X#
  51. Global PLAYER_Y#
  52. Global PLAYER_SCORE
  53. Global HI_SCORE
  54.  
  55. Global timer
  56. Global frames
  57. Global starson
  58. Global game_pause_frame
  59. Global game_accept_pause
  60. Global game_pause_stat
  61. Global hypercount#        ;a "#" symbol after the variable name means it can hold a FLOATING POINT number, i.e.: 190.1234
  62. Global pausecount        ;without the "#" symbol, the variable is, by default, an INTEGER (Whole) number, i.e.: 190
  63. Global cloakon#            ;use the symbols when you are *sure* that you want it to hold specific types of data:
  64. Global frame1            ;# - floating point
  65. Global frame2            ;% - integer (whole number)
  66. Global frame3            ;$ - string (text, i.e.: "MYKE 12345"
  67. Global frame4            ;
  68. Global frame5
  69. Global frame6
  70. Global frame7
  71. Global frame8
  72. Global tempstr$
  73.  
  74. timer = CreateTimer(50) ;create a timer set at 50ms (game speed) - play with this to see how you can increase or decrease the speed of the game.
  75.                         ;this should be set at a speed which will look near enough the same on *every* PC it will be played on.
  76.                         ;My PC (a 733MHz PIII with an nVidia GeForce card) will handle upwards of 150 frames per second, quite happily
  77.                         ;but 'lesser' machines will not. 50, therefore, is quite sensible For a game of this nature, who's minimum system spec
  78.                         ;will be something like a PII 300MHz machine (i.e.: Blitz Basic's minimum spec!)
  79.  
  80. ;NOTE: there's no need to organise your variable declarations, as I have here, into sections. They can appear in any order you like, before the main program begins.
  81. ;I just do this, 'cos it looks right professional! :))))
  82.  
  83. ;picture/animation (and related) variables
  84. Dim game_stars(5)            ;these 3 are ARRAYS. An array is automatically Global, but requires the Keyword (Yellow bit) DIM instead. This means "Dimension".
  85. Dim game_icons(4)            ;the arrays have single dimensions (imagine one straight line of boxes, each that can contain a single variable) 0 to.. (the number in brackets)
  86. Global game_icon_dot
  87. Global game_player
  88. Global game_player_frame
  89. Global game_player_dot
  90. Global game_bullet_player
  91. Global game_gameover
  92. Global game_paused
  93.  
  94. ;Types are like Structures in C. You have a "Type" called whatever. Then you can make multiple versions of the type. Each version of the Type has the same properties, i.e.:
  95. ;a FISH (the Type) has EYES, MOUTH, SCALES And FINS (it's properties) - ALL FISH have these properties.
  96. ;a DOG (the Type) has EYES, MOUTH, FUR and TAIL (it's properties) - ALL DOGS have these properties (look like this.)
  97. Type stars                        ;create "Type" for parallex stars
  98.     Field depth,x#,y#            ;each star has a depth, x and y position
  99. End Type
  100.  
  101. Type icons                        ;same for icons
  102.     Field x#,y#,style,frame#
  103. End Type
  104.  
  105. ;this is for the bullets. I've used an array, rather than a type (which would have been just as good in this case) to show you how MULTIDIMENSIONAL arrays can work.
  106. Const bulletnum = 500
  107. Global bulletlimiter
  108. Global nextbullet = 0
  109. Dim bullets(bulletnum-1,7) ;create an array for 'bulletnum' (0 to bulletnum -1) on-screen bullets with 8 values per bullet:
  110.                         ;0 = bullet_x, 1 = bullet_y, 2 = bullet_angle, 3 = bullet_speed,
  111.                         ;4 = bullet_style, 5 = bullet_animframe, 6 = bullet_origin_x, 7 = bullet_origin_y
  112.                         ;we'll say that a bullet's style can also say whether or not it's in use, i.e.: 0 = off, 1 = player, 2 = enemy1
  113.  
  114.  
  115. ;this code makes 4 'objects' in a "Type" called "ICONS".
  116. For i = 1 To 4                    ;do this 1, 2, 3, 4 times
  117.     icon.icons = New icons        ;create a new icon
  118.     icon\style = i                ;the icon style for each new icon is equal to the increment of i (i.e.: 1, 2, 3 or 4!)
  119.     icon\frame = Int(Rnd(0,5))    ;create a random frame number between 0 and 5 for each new icon
  120. Next
  121.  
  122. menustars = SCREEN_HEIGHT/3 ;generate a number of stars, so that they look dense enough on all test resolutions
  123. starson = 1 ;tells the program to show the stars (see later)
  124. For i=0 To menustars                    ;create <menustars> number of stars in the STARS type
  125.     star.stars=New stars                ;add a new star for each increment of i
  126. Next
  127.  
  128. ;this code loads the image numbers into an array called "game_ stars", which we DIMmed earlier. It has 6 containers (0,1,2,3,4,5) but I'm only using 1 to 5!
  129. ;an "image number" is what Blitz uses to reference graphics held in the Video Memory, i.e.:
  130. ;1. Image number 12 is a picture of a flower.
  131. ;2. Make a variable called "flower_pic" = 12
  132. ;3. Wherever Blitz is told to draw "flower_pic", reference image number 12 in the Video Memory.
  133. game_stars(1) = LoadImage("GfxRes/backg-star-1.bmp")    ;container (1) in "game_stars" holds the image number for this picture ("GfxRes/backg-star-1.bmp")
  134. game_stars(2) = LoadImage("GfxRes/backg-star-2.bmp")    ;etc..
  135. game_stars(3) = LoadImage("GfxRes/backg-star-3.bmp")
  136. game_stars(4) = LoadImage("GfxRes/backg-star-4.bmp")
  137. game_stars(5) = LoadImage("GfxRes/backg-star-5.bmp")
  138. For i = 1 To 5
  139.     MaskImage game_stars(i),255,0,255    ;mask the images for each star, so that MAGENTA (255,0,255) is the transparent colour
  140. Next
  141.  
  142. ;similarly, this code loads the image numbers into an array called "game_icons"
  143. ;however, these are images that contain the frames of an Animation, so a different Load command is used.
  144. game_icons(1) = LoadAnimImage("GfxRes/icon-boost.bmp",32,32,0,6)    ;LoadAnimImage has the same structure as LoadImage, with additional numbers after the picture filename
  145. game_icons(2) = LoadAnimImage("GfxRes/icon-shield.bmp",32,32,0,6)    ;these are: Frame Width (pixels), Frame Height (pixels), Starting Framenumber (usually 0)
  146. game_icons(3) = LoadAnimImage("GfxRes/icon-cloak.bmp",32,32,0,6)    ;and the Number of Frames in the Image (as *you* would count them (in this case 6)
  147. game_icons(4) = LoadAnimImage("GfxRes/icon-jump.bmp",32,32,0,6)        ;have a look at the file "icon-boost" in Paint Shop Pro and see for yourself the 6 frames of animation.
  148. For i = 1 To 4
  149.     MaskImage game_icons(i),255,0,255    ;mask the images for each icon, so that MAGENTA (255,0,255) is the transparent colour
  150. Next
  151.  
  152. ;notice in the following code, we're loading (and MASKING) graphics in exactly the same way as before, but into regular variables instead of arrays.
  153. ;this next bit is all animations
  154. game_player = LoadAnimImage("GfxRes/player-ship.bmp",80,80,0,72) ;load in the 'sprite' for the player ship
  155. MaskImage game_player,255,0,255 ;mask the images for the player ship, so that MAGENTA (255,0,255) is the transparent colour
  156. game_bullet_player = LoadAnimImage("GfxRes/bullet-player.bmp",10,10,0,6)    ; the blue player bullet animation
  157. MaskImage game_bullet_player,255,0,255 ;mask the images
  158. ;these are all plain single-frame pictures
  159. ;game piccies
  160. game_gameover = LoadImage("GfxRes/game-gameover.bmp")        ;the game over logo, which I tend to see a lot of.. :(
  161. game_paused = LoadImage("GfxRes/game-paused.bmp")            ;the paused logo
  162. game_player_dot = LoadImage("GfxRes/player-radardot.bmp")    ;radar dots for the player and bonus icons respectively
  163. game_icon_dot = LoadImage("GfxRes/icon-radardot.bmp")
  164. MaskImage game_gameover,255,0,255
  165. MaskImage game_paused,255,0,255
  166.  
  167. ;Right! That's it, we've set up *everything* we're going to need from outside the program.
  168. game_loop() ;start the proper program loop by 'calling' the function called "menu_loop()" - which, conveniently, is just coming up!!!
  169.  
  170. ;this function keeps the game loop going.. It starts playing tunes and sets a couple of variables. 
  171. ;Then it goes into a never ending loop which carries out a sequence of checks and function calls, until such time as we want to stop it!
  172. Function game_loop()
  173.     FLAG_GAMEON = 1 ;tells the program that the game is running.
  174.     game_initialise()     ;calls a function called "game_initialise()" (which is next in the code) which
  175.                         ;just gives the player full energy and a score of 0 etc..)
  176.     Repeat        ;as with the menu, we want to cycle though the process of updating/drawing forever, until such time as the game has ended.
  177.         If FLAG_GAMEON = 1 Then        ;.. so, if FLAG_GAMEON is 1, then "do" the following.
  178.             game_loop_update()                                ;call the game_loop_update() function
  179.         Else
  180.             FlushKeys                
  181.             End                    ;if FLAG_GAMEON isn't 1, we End the program
  182.         End If
  183.     Forever
  184. End Function
  185.  
  186. ;As described a minute ago, this function sets up the game variables as they should be
  187. ;at the start of every game, i.e.: Player Shields are full, the score is 0 etc..
  188. Function game_initialise()
  189.     FLAG_DEBUG = 1                    
  190.     FLAG_GAMESTARTER = 1
  191.     hypercount = 102
  192.     FLAG_PAUSE = 0
  193.     PLAYER_SCORE = 0
  194.     PLAYER_TIME = 0
  195.     PLAYER_ANGLE = 0
  196.     PLAYER_SPEED = 0
  197.     PLAYER_SHIELD = 192            ;the width of the game_level image is 192. Rather than working out a percentage of 100, it's much
  198.     PLAYER_BOOSTERS = 192        ;easier to use the width of the image on such BAR type displays.
  199.     PLAYER_CLOAK = 192            
  200.     PLAYER_JUMPS = 5
  201.     game_player_randomize()            ;calls a function that randomizes a player's position on the map
  202.     game_stars_randomize()            ;calls a function that randomizes the star positions
  203.  
  204.     ;this next bit is the first time you'll have seen a TYPE cycle.
  205.     ;Just like a normal "For i = 0 to 20" loop, this goes through each Version of a type
  206.     ;and set's it's properties. (i.e.: That FISH type has a SCALES property. Here we tell it that this particular Fish's Scales are GOLD!)
  207.     For icon.icons = Each icons
  208.         icon\x = Rnd(0,GAME_AREA_X)        ;for each of the 4 icons on the play area at any one point, we need a random x and y position.
  209.         icon\y = Rnd(0,GAME_AREA_Y)
  210.     Next
  211. End Function
  212.  
  213. ;once again, like it's menu equivalent, "game_loop_update()" is a function which analyses player input, working out all the new
  214. ;coordinate positions and anything else which needs deciding before updating the screen display.
  215. Function game_loop_update()
  216.     frames = WaitTimer(timer)
  217.     For i = 1 To frames
  218.         If KeyDown(KEY_PAUSE)                                    ;checks to see if the user has pressed the "PAUSE" key
  219.             FlushKeys
  220.             If game_accept_pause = 1                            ;the "game_accept_pause" variable is used in the same way as "menu_accept_quit" earlier.
  221.                                                                 ;because we're using SCANCODES, the program will register a number of qualifying cases where
  222.                                                                 ;when this check is performed, the key is still held down (at 50 frames per second, if the user
  223.                                                                 ;held down the key for half a second, the KEYDOWN function would fire around 25 times!)
  224.                                                                 
  225.                 If FLAG_PAUSE = 0 Then                            ;If FLAG_PAUSE is 0 then..
  226.                     FLAG_PAUSE = 1                                ;make FLAG_PAUSE = 1
  227.                     game_accept_pause = 0                        ;don't accept any more "PAUSE" button presses until "game_accept_pause" is set back to 1
  228.                     game_pause_frame = 1                        ;make "game_pause_frame" = 1 which, similarly to "menu_frame" earlier will enable the flashing of "PAUSED".
  229.                 Else
  230.                     FLAG_PAUSE = 0                                ;If FLAG_PAUSE isn't 0 (the game was paused) then..
  231.                     game_accept_pause = 0                        ;do exactly the same, but set FLAG_PAUSE to 0.
  232.                     game_pause_frame = 1
  233.                 End If
  234.             End If
  235.         End If
  236.         If KeyDown(KEY_SAVESCREEN)        ;If the "SCREENSAVE" button is pressed..
  237.             FlushKeys                    ;this functions exactly the same as in menu_loop_update()
  238.             FLAG_SAVESCREEN = 1
  239.         End If
  240.         If KeyDown(KEY_QUIT)        ;If the "QUIT" button is pressed..
  241.             FlushKeys
  242.             hypercount = 0
  243.             cloakon = 0
  244.             FLAG_GAMEON=0             ;set FLAG_GAMEON to equal 0. Back in the "game_loop()" function, this will cause the code to jump back to the menu.
  245.         End If
  246.  
  247.         If FLAG_PAUSE = 0 Then                            ;this is really easy! If the game is paused then *don't* do any of the following code. No values will change,
  248.                                                         ;hence nothing will move on the screen when it comes to updating it later! :)
  249.                                                         
  250.                 If KeyDown(KEY_HYPER)                    ;if the "HYPER" key is pressed then..
  251.                     If PLAYER_JUMPS > 0 Then
  252.                         If hypercount = 0 Then                ;(if "hypercount" is 0, then we're not already in the middle of a HyperJump, so let's set things off!)
  253.                             hypercount = 1                        ;by setting "hypercount" to 1, we'll set off a chain of events later on..
  254.                             PLAYER_JUMPS = PLAYER_JUMPS - 1        ;subtract the number of Jumps a player has left by 1
  255.                             If PLAYER_JUMPS <= 0 Then            ;if the number of jumps left is 0 or less, then the above subtraction will make it "-1", so..
  256.                                 PLAYER_JUMPS = 0                ;put it back to 0.
  257.                             End If
  258.                         End If
  259.                     End If
  260.                     FlushKeys
  261.                 End If
  262.                 If hypercount = 0 Then                        ;as long as we're not in the middle of a hyperjump, do the following..
  263.                 
  264.                     If KeyDown(KEY_CLOAK)            ;if the CLOAK key is pressed then
  265.                     
  266.                         If PLAYER_CLOAK > 2 Then        ;if the player has enough (2 points of) PLAYER_CLOAK left, then..
  267.                             cloakon = cloakon + 1                                    ;the cloakon value is incremented so that later on, we can do the flickering effect
  268.                             PLAYER_CLOAK = PLAYER_CLOAK - INCR_CLOAK_DOWN            ;subtract some PLAYER_CLOAK ability at a rate of "INCR_CLOAK_DOWN"
  269.                             
  270.                         Else                            ;if the player doesn't have enough PLAYER_CLOAK left then
  271.                             cloakon = 0                        ;reset the "cloakon" value to 0
  272.                             PLAYER_CLOAK = 0                ;Keep the PLAYER_CLOAK value at 0, so that it doesn't build up...
  273.                         End If
  274.                         FlushKeys
  275.                     Else                            ;if the CLOAK key isn't pressed then
  276.                         cloakon = 0                            ;reset the "cloakon" value to 0
  277.                         If PLAYER_CLOAK < 192                                ;if the player has less than the top value (192 points) of PLAYER_CLOAK then..
  278.                             PLAYER_CLOAK = PLAYER_CLOAK + INCR_CLOAK_UP            ;Slowly build up the PLAYER_CLOAK value.
  279.                         Else
  280.                             PLAYER_CLOAK = 192                                ;otherwise cap the PLAYER_CLOAK value at 192 points.
  281.                         End If
  282.                         FlushKeys
  283.                     End If
  284.                     If KeyDown(KEY_BOOST)                            ;the BOOST key works in exactly the same way as the CLOAK key
  285.                         If PLAYER_BOOSTERS > 2 Then
  286.                             If PLAYER_SPEED < (SPEED_MAX*3) Then
  287.                                 PLAYER_SPEED = PLAYER_SPEED + (INCR_SPEED * 3)
  288.                             End If
  289.                             PLAYER_BOOSTERS = PLAYER_BOOSTERS - INCR_BOOSTERS_DOWN
  290.                         Else
  291.                             PLAYER_BOOSTERS = 0
  292.                         End If
  293.                         FlushKeys
  294.                     Else
  295.                         If PLAYER_BOOSTERS < 192
  296.                             PLAYER_BOOSTERS = PLAYER_BOOSTERS + INCR_BOOSTERS_UP
  297.                         Else
  298.                             PLAYER_BOOSTERS = 192
  299.                         End If
  300.                         FlushKeys
  301.                     End If
  302.                     If KeyDown(KEY_FIRE) Then                    ;if the "FIRE" key is pressed, then..
  303.                         If bulletlimiter = 0 Then                    ;the "bulletlimiter" value works in exactly the same way as "game_accept_pause" earlier
  304.                                                                     ;in that we don't want too many bullets spraying out of the player, due to SCANCODE/framerate issues
  305.                             bulletlimiter = 1                        ;so we set the "bulletlimiter value to 1, so that until we say so (a bit later) no more "FIRE" keypresses
  306.                                                                     ;will trigger.
  307.                                                                     
  308.                             createbullet(PLAYER_X,PLAYER_Y,PLAYER_ANGLE,PLAYER_SPEED,1)        ;however, assuming we've got a successful "FIRE" event, let's create some bullets
  309.                                                                                             ;on the screen by calling the "createbullet()" function.. This is pretty cool, so
  310.                                                                                             ;see the function itself later on for explainations!
  311.                         End If
  312.                         FlushKeys
  313.                     End If
  314.                     If KeyDown(KEY_CLOCKWISE)                            ;if "CLOCKWISE" key is pressed then..
  315.                         PLAYER_ANGLE = PLAYER_ANGLE + INCR_ROTATE            ;Add "INCR_ROTATE" degrees to the current PLAYER_ANGLE
  316.                         FlushKeys
  317.                         If PLAYER_ANGLE >= 360 Then                            ;if the PLAYER_ANGLE is 360, then reset it to 0.
  318.                             PLAYER_ANGLE = PLAYER_ANGLE - 360
  319.                         End If
  320.                     End If
  321.                     If KeyDown(KEY_ANTICWISE)                            ;exactly the same, but Subtract "INCR_ROTATE" from the player angle and
  322.                         PLAYER_ANGLE = PLAYER_ANGLE - INCR_ROTATE        ;reset it to (for example) 355, if the angle is -5.
  323.                         FlushKeys
  324.                         If PLAYER_ANGLE < 0 Then
  325.                             PLAYER_ANGLE = PLAYER_ANGLE + 360
  326.                         End If
  327.                     End If
  328.                     If KeyDown(KEY_SPEEDUP) Then                        ;if the "SPEEDUP" key is pressed.
  329.                         If PLAYER_SPEED < SPEED_MAX                            ;as long as the player speed is less than the maximum speed (SPEED_MAX), then
  330.                             PLAYER_SPEED = PLAYER_SPEED + INCR_SPEED        ;Add "INCR_SPEED" to the player's speed value
  331.                             FlushKeys
  332.                         Else
  333.                             PLAYER_SPEED = PLAYER_SPEED - INCR_SLOW            ;if the PLAYER_SPEED is not less than the maximum speed then take "INCR_SLOW" off of it!
  334.                             FlushKeys
  335.                         End If
  336.                     Else                                                ;if the key isn't being pressed, then..
  337.                         If PLAYER_SPEED > 0 Then                            ;as long as the player speed is greater than 0, then take "INCR_SLOW" off the current value
  338.                             PLAYER_SPEED = PLAYER_SPEED - INCR_SLOW            ;(this is an easy "No power" decelaration for the space ship)
  339.                         End If
  340.                         FlushKeys
  341.                     End If
  342.                     If KeyDown(KEY_SPEEDDOWN)                            ;exactly the same thing, but with the ship's thrusters in reverse! :)
  343.                         If PLAYER_SPEED > SPEED_MIN
  344.                             PLAYER_SPEED = PLAYER_SPEED - INCR_SPEED
  345.                             FlushKeys
  346.                         Else
  347.                             PLAYER_SPEED = SPEED_MIN
  348.                             FlushKeys
  349.                         End If
  350.                     Else
  351.                         If PLAYER_SPEED < 0 Then
  352.                             PLAYER_SPEED = PLAYER_SPEED + INCR_SLOW
  353.                         End If
  354.                     End If
  355.                 End If    ;end of the "If we're not in the middle of a hyperjump" IF statement
  356.                 
  357.                 ;this next peice of code updates the player position on the map, relative to it's Speed and Angle and it's last position
  358.                 PLAYER_X = PLAYER_X + (PLAYER_SPEED*(Sin(PLAYER_ANGLE)/2))
  359.                 PLAYER_Y = PLAYER_Y - (PLAYER_SPEED*(Cos(PLAYER_ANGLE)/2))
  360.                 If PLAYER_X < 0 Then                        ;if the PLAYER_X value is less than 0, then wrap your position around the map
  361.                     PLAYER_X = (PLAYER_X + GAME_AREA_X)        ;by adding the GAME_AREA_X value to the negative value, i.e.: -5 becomes 19995 on a 20000 X pixel map.
  362.                 End If
  363.                 If PLAYER_X > GAME_AREA_X Then                ;the same in reverse, i.e. 20004 becomes 4 on the same map.
  364.                     PLAYER_X = (PLAYER_X - GAME_AREA_X)
  365.                 End If
  366.                 If PLAYER_Y < 0 Then                        ;and now the same for the Y direction
  367.                     PLAYER_Y = (PLAYER_Y + GAME_AREA_Y)
  368.                 End If
  369.                 If PLAYER_Y > GAME_AREA_Y Then
  370.                     PLAYER_Y = (PLAYER_Y - GAME_AREA_Y)
  371.                 End If
  372.     
  373.             For icon.icons=Each icons                ;the "icons" don't move from their randomly set x,y position, so all we need to do for them is
  374.                 icon\frame = icon\frame+.5            ;update their animation frame number. There are 6 frames, and we're incrementing at 0.5 frames per update.
  375.                 If Int(icon\frame) = 6 Then            ;in real terms, this means we'll be updating the frame number every 2 updates.
  376.                     icon\frame = 0                    ;Because the icon animations are simple 0 to 5 cycling animations, when the frame number reaches 6, we flip it back to 0
  377.                 End If                                ;to start the sequence again.
  378.             Next
  379.             
  380.             ;this next bit of code creates the "simple but effective" Hyperjump event, based entirely on the value of "hypercount" being set to 1, earlier in the code.
  381.             If hypercount > 0 Then
  382.                 If (hypercount/2 = Int(hypercount/2)) Then    ;this line says "If the value of 'hypercount' is an EVEN number"
  383.                                                             ;because 5 (an odd number) would be 2.5 when devided by 2, but conversion to an INTeger gives 3.
  384.                                                             ;2.5 does NOT equal 3!
  385.                     ;all of this simply rotates the HyperJump ships in different offset directions
  386.                     ;the only difference is, we're not bothering with degrees here, just animation frame numbers, i.e.: 355 degrees is frame 71 (i.e.: 355/5 degree increment)
  387.                     frame1 = frame1 + 3
  388.                     frame2 = frame2 - 3
  389.                     frame3 = frame1 + 9
  390.                     frame4 = frame2 - 9
  391.                     frame5 = frame1 + 36
  392.                     frame6 = frame2 - 36
  393.                     frame7 = frame1 + 54
  394.                     frame8 = frame2 - 54
  395.                     If frame1 >=72 Then
  396.                         frame1 = frame1-72
  397.                     End If
  398.                     If frame1 < 0 Then
  399.                         frame1 = frame1+72
  400.                     End If
  401.                     If frame2 >=72 Then
  402.                         frame2 = frame2-72
  403.                     End If
  404.                     If frame2 < 0 Then
  405.                         frame2 = frame2+72
  406.                     End If
  407.                     If frame3 >=72 Then
  408.                         frame3 = frame3-72
  409.                     End If
  410.                     If frame3 < 0 Then
  411.                         frame3 = frame3+72
  412.                     End If
  413.                     If frame4 >=72 Then
  414.                         frame4 = frame4-72
  415.                     End If
  416.                     If frame4 < 0 Then
  417.                         frame4 = frame4+72
  418.                     End If
  419.                     If frame5 >=72 Then
  420.                         frame5 = frame5-72
  421.                     End If
  422.                     If frame5 < 0 Then
  423.                         frame5 = frame5+72
  424.                     End If
  425.                     If frame6 >=72 Then
  426.                         frame6 = frame6-72
  427.                     End If
  428.                     If frame6 < 0 Then
  429.                         frame6 = frame6+72
  430.                     End If
  431.                     If frame7 >=72 Then
  432.                         frame7 = frame7-72
  433.                     End If
  434.                     If frame7 < 0 Then
  435.                         frame7 = frame7+72
  436.                     End If
  437.                     If frame8 >=72 Then
  438.                         frame8 = frame8-72
  439.                     End If
  440.                     If frame8 < 0 Then
  441.                         frame8 = frame8+72
  442.                     End If
  443.                 End If    ;end of the "if hypercount is EVEN" IF statement
  444.                 
  445.                 ;this bit increases the value of "hypercount" until it reaches 200
  446.                 hypercount = hypercount + 1
  447.                 If hypercount > 0 And hypercount <= 102 Then    ;between 0 and 102, the player speed increases
  448.                     PLAYER_SPEED = PLAYER_SPEED + 2
  449.                 ElseIf hypercount > 102 And hypercount < 200 Then    ;between 102 and 200, the player speed decreases (but only if FLAG_GAMESTARTER is 0)
  450.                     If FLAG_GAMESTARTER = 0 Then                    ;this is because when the game starts, the player speed is 0, but we've faked being in
  451.                         PLAYER_SPEED = PLAYER_SPEED - 2                ;the middle of a hyperjump. Without this FLAG, the player ship would start each game
  452.                     End If                                            ;travelling at about -90 speed backwards, which would just be weird! :)
  453.                 End If
  454.                 If hypercount = 100 Then
  455.                     game_stars_randomize()    ;half way through the Hyperjump sequence, the "game_stars_randomize()" function is called, which changes all the star positions    
  456.                                             ;and depths, to give the impression we've moved to a completely different part of space
  457.                 End If
  458.                 If hypercount/10 = Int(hypercount/10) Then
  459.                     game_player_randomize()        ;every 10 updates, the function "game_player_randomize()" is called. This randomly jumps the player around the map
  460.                                                 ;and confuses the hell out of the bad guys! (well it will by next month's tutorial!!) ;))
  461.                 End If
  462.                 If hypercount = 200 Then        ;if the "hypercount" variable reaches 200, then stop the sequence and reset the value back to 0
  463.                     hypercount = 0
  464.                     FLAG_GAMESTARTER = 0        ;also, when the game first starts we were in the middle of a hyperjump. Resetting this FLAG back to 0 means that
  465.                                                 ;the next hyperjump sequence will decrease the speed after "hypercount" gets to 103
  466.                 End If
  467.             Else                            ;if we're not in the middle of a hyperjump event, then:
  468.                 frame1=game_player_frame-1    ;this bit is just for the DEBUG mode. It was designed to check that 360 degrees became 0 degrees and vice versa correctly
  469.                 frame2=game_player_frame+1
  470.                 If frame1 < 0 Then
  471.                     frame1 = frame1 + 72
  472.                 End If
  473.                 If frame2 >= 72 Then
  474.                     frame2 = frame2 - 72
  475.                 End If
  476.             End If    ;end of the "Are we in the middle of a Hyperjump" IF statement
  477.             
  478.             ;the parralex stars move relative to the player and is just the same "menustars" number of stars
  479.             ;scrolled at various speeds, wrapping around the screen.
  480.             ;it's a fairly cheap, but effective way of creating a nice illusion of speed!
  481.             If starson=1 Then                ;if, at the beginning of the program, you set "starson" to 0, the stars will disappear.
  482.                                             ;the game would also feel pretty bloody wierd.. hold on.. yep.. Absolutely mad! Try it! :)
  483.                 For star.stars=Each stars
  484.                     ;the following two lines move each version of the "stars" Type an x and y distance relative to the player's speed and angle
  485.                     ;with a devision relative to the depth of the star to make the smallest stars move slower than the biggest
  486.                     ;thus we have our parallex effect.
  487.                     
  488.                     ;it might be of interest to know that these two lines were based on the OLDSKOOL demo which comes with Blitz Basic
  489.                     ;and was the starting point for the whole CELESTIAL RIFT game concept! Thanks a lot, Mr Mikkel L°kke!! :)
  490.                     star\y=(star\y+PLAYER_SPEED*(Cos(360-PLAYER_ANGLE)/(6-star\depth+1)))
  491.                     star\x=(star\x+PLAYER_SPEED*(Sin(360-PLAYER_ANGLE)/(6-star\depth+1)))
  492.                     ;the maximum pixel width of for the biggest star image is 5 pixels
  493.                     ;the following IF statements wrap the stars around the screen border when they reach the extremities
  494.                     If star\x < -5 Then
  495.                         star\x = star\x + (SCREEN_WIDTH + 5)
  496.                     End If
  497.                     If star\x > SCREEN_WIDTH Then
  498.                         star\x = star\x - (SCREEN_WIDTH + 5)
  499.                     End If
  500.                     If star\y <= -5 Then
  501.                         star\y = star\y + (SCREEN_HEIGHT + 5)
  502.                     End If
  503.                     If star\y >= SCREEN_HEIGHT
  504.                         star\y = star\y - (SCREEN_HEIGHT + 5)
  505.                     End If
  506.                 Next
  507.             End If    ;end of the "are the stars going to be shown" IF statement
  508.  
  509.             ;the following lines calculate all the bullet positions, relative to their originally set SPEED and ANGLE from the "createbullet" function.
  510.             For i = 0 To bulletnum-1
  511.                 If bullets(i,4) > 0 Then        ;if the bullet isn't 0, i.e.: it's "on"
  512.                 
  513.                     bullets(i,0) = bullets(i,0) + (bullets(i,3)*(Sin(bullets(i,2))/2))    ;bullet x position = bullet x position + (bullet speed * (SIN (bullet angle) / 2)
  514.                     bullets(i,1) = bullets(i,1) - (bullets(i,3)*(Cos(bullets(i,2))/2))    ;bullet y position = bullet y position + (bullet speed * (COS (bullet angle) / 2)
  515.                                 ;try turning these last two lines off for a crazy pulsing effect of bullets that you can use
  516.                                 ;to surround the player, creating a kind of enemy-deadly minefield.. Madness! :)
  517.                     
  518.                     bullets(i,5) = bullets(i,5) + 1        ;increases the animation frame of the bullet
  519.                     If bullets(i,5) = 6 Then    ;if the animation frame is 6 then flip it back to 0 (the bullet animation runs frames 0, 1, 2, 3, 4, 5, 0, 1, 2 ... etc)
  520.                         bullets(i,5) = 0
  521.                     End If
  522.                     
  523.                     ;as with the player and enemies, this next bit wraps the bullets around the map extremities
  524.                     If bullets(i,0) < 0 Then
  525.                         bullets(i,0) = (bullets(i,0) + GAME_AREA_X)
  526.                     End If
  527.                     If bullets(i,0) > GAME_AREA_X Then
  528.                         bullets(i,0) = (bullets(i,0) - GAME_AREA_X)
  529.                     End If
  530.                     If bullets(i,1) < 0 Then
  531.                         bullets(i,1) = (bullets(i,1) + GAME_AREA_X)
  532.                     End If
  533.                     If bullets(i,1) > GAME_AREA_Y Then
  534.                         bullets(i,1) = (bullets(i,1) - GAME_AREA_Y)
  535.                     End If
  536.                     
  537.                     ;like the enemies "distance from player", this bit checks if a bullet has gone a certain distance from it's origin
  538.                     temp_x1# = bullets(i,0) - bullets(i,6) ;origin x on the right
  539.                     temp_y1# = bullets(i,1) - bullets(i,7) ;origin y on the top
  540.                     temp_x2# = bullets(i,6) - bullets(i,0) ;origin x on the left
  541.                     temp_y2# = bullets(i,7) - bullets(i,1) ;origin y on the bottom
  542.  
  543.                     ;wraps distances around the map extremities
  544.                     If temp_x1# < 0 Then
  545.                         temp_x1# = temp_x1# + GAME_AREA_X
  546.                     End If
  547.                     If temp_x1# > GAME_AREA_X Then
  548.                         temp_x1# = temp_x1# - GAME_AREA_X
  549.                     End If
  550.                     If temp_y1# < 0 Then
  551.                         temp_y1# = temp_y1# + GAME_AREA_Y
  552.                     End If
  553.                     If temp_x1# > GAME_AREA_X Then
  554.                         temp_y1# = temp_y1# - GAME_AREA_Y
  555.                     End If
  556.                     If temp_x2# < 0 Then
  557.                         temp_x2# = temp_x2# + GAME_AREA_X
  558.                     End If
  559.                     If temp_x2# > GAME_AREA_X Then
  560.                         temp_x2# = temp_x2# - GAME_AREA_X
  561.                     End If
  562.                     If temp_y2# < 0 Then
  563.                         temp_y2# = temp_y2# + GAME_AREA_Y
  564.                     End If
  565.                     If temp_x2# > GAME_AREA_X Then
  566.                         temp_y2# = temp_y2# - GAME_AREA_Y
  567.                     End If
  568.                     
  569.                     ;calculates the shortest distance
  570.                     If Abs(temp_x1#) < Abs(temp_x2#) Then
  571.                         temp_x# = Abs(temp_x1#)
  572.                     Else
  573.                         temp_x# = Abs(temp_x2#)
  574.                     End If
  575.                     If Abs(temp_y1#) < Abs(temp_y2#) Then
  576.                         temp_y# = Abs(temp_y1#)
  577.                     Else
  578.                         temp_y# = Abs(temp_y2#)
  579.                     End If
  580.                     
  581.                     ;back to PYTHAGORAS to work out the "As the crow flies" distance from the bullet's original starting point
  582.                     temp_x# = Abs(temp_x# / 200)
  583.                     temp_y# = Abs(temp_y# / 200)
  584.                     temp_hyp# = (temp_x#*temp_x#) + (temp_y#*temp_y#)
  585.                     temp_hyp# = Sqr(temp_hyp#)
  586.  
  587.                     ;if the bullet has travelled "5" units from it's starting point, then..
  588.                     If temp_hyp# > 5 Then
  589.                         bullets(i,4) = 0    ;turn the bullet off
  590.                     End If
  591.                 End If
  592.             Next    ;end of bullet coordinate repositioning loop
  593.             
  594.             ;this is the player's bullet limiting code, basically only allowing the player to fire every 10 frames (otherwise it looks more like the player is spraying water!!)
  595.             If bulletlimiter > 0 Then
  596.                 bulletlimiter = bulletlimiter + 1
  597.                 If bulletlimiter = 10 Then ;value essentially sets the fire-rate (the lower the number, the faster the fire rate!)
  598.                     bulletlimiter = 0
  599.                 End If
  600.             End If
  601.             
  602.             PLAYER_SCORE = PLAYER_SCORE + 1        ;if the game is in progress, then increase the PLAYER_SCORE by 1 every screen update
  603.                                                     ;this acts as a kind of survival bonus for the more defensive player
  604.                 If PLAYER_SCORE >= HI_SCORE Then
  605.                     HI_SCORE = PLAYER_SCORE
  606.                 End If
  607.             
  608.         End If ;end of "IF FLAG_PAUSE = 0" IF Statement
  609.         
  610.         ;this flashes the "PAUSED" caption on and off when needs be!
  611.         game_pause_frame = game_pause_frame + 1
  612.         If game_pause_frame = 25 Then
  613.             game_pause_frame = 1
  614.             game_accept_pause = 1
  615.             If game_pause_stat = 1 Then
  616.                 game_pause_stat = 0
  617.             Else
  618.                 game_pause_stat = 1
  619.             End If
  620.         End If
  621.  
  622.     Next    ;end of the "for i = 1 to frames" FOR loop
  623.     
  624.     game_draw_update()    ;finally, draw all the pictures on the screen, based on their (possibly) new positions.
  625. End Function
  626.  
  627. ;this function draws the game graphics in their freshly calculated positions
  628. Function game_draw_update()
  629.     SetBuffer BackBuffer()    ;draw all of the following to the backbuffer
  630.     ClsColor 0,0,0            ;changes the CLearScreen colour to black (0,0,0)
  631.     Cls
  632.     If starson=1 Then        ;draw all of the stars using their correct pictures, at the correct x and y positions
  633.         For star.stars=Each stars ;(for each star in type 'stars' do the following..)
  634.             DrawImage game_stars(star\depth),star\x,star\y    ;using the depth property of "stars" as the Array position
  635.         Next
  636.     End If
  637.     
  638.         ;this FOR Type loop draws all the versions of "icons" at their screen-position - relative to the PLAYER coordinates
  639.         ;in the current animation frame. It also checks for the non-transparent areas of the ICON image touching the non-
  640.         ;transparent areas of the PLAYER image and updates the PLAYER's relavent energy-level values.
  641.         For icon.icons=Each icons
  642.         
  643.             ;this line draws the relavant icon image at coordinates "x" and "y" on (or off) the screen
  644.             ;the correct icon image is chosen using the "icons"'s style as it's array position
  645.             ;the x and y coordinates are worked out by subtracting the PLAYER's current position from the "icons"'s current position
  646.             ;notice that we're using the same style of "SCREEN_WIDTH\2 - Half the ImageWidth of the Image" idea from the
  647.             ;"menu_draw_update()" code?
  648.             DrawImage game_icons(icon\style), (((SCREEN_WIDTH/2)-ImageWidth(game_icons(icon\style))/2) - (PLAYER_X - icon\x)), (((SCREEN_HEIGHT/2)-ImageWidth(game_icons(icon\style))/2) - (PLAYER_Y - icon\y)),Int(icon\frame)
  649.  
  650.         Next    ;end of the "icons" FOR loop
  651.  
  652.         ;now we'll do the same for all the bullets on (or off) the screen    
  653.         For i = 0 To bulletnum-1    ;this cycles though the array from position 1 to the final bullet number in the array..
  654.                                     ;we use "bulletnum - 1" because there are (for example) 600 possible bullets that are stored
  655.                                     ;in an array as 0, 1, 2, 3 ... 596, 597, 598 and 599
  656.         
  657.             Select bullets(i,4)        ;whose bullet is it? remember when we originally DIMmed this Array, I said that 0 was off, 1 was a PLAYER bullet and 2 was an enemy bullet?
  658.                 Case 1
  659.                 
  660.                     ;if it's a player bullet then..
  661.                     ;draw this bullet at it's position, relative to the player, in it's current animation frame
  662.                     DrawImage game_bullet_player,(((SCREEN_WIDTH/2)-ImageWidth(game_bullet_player)/2) - (PLAYER_X - bullets(i,0))), (((SCREEN_HEIGHT/2)-ImageWidth(game_bullet_player)/2) - (PLAYER_Y - bullets(i,1))),bullets(i,5)
  663.             End Select
  664.         Next    ;end of the "bullet drawing/collision detecting" FOR loop
  665.  
  666.     ;this section draws the frames of "animation" for the hyperjump, or - if we're not mid hyperjump - draws the regular player frames
  667.     ;the hyperjump bits look quite complecated, but it's just x and y positions that are changing in relation to the value of "hypercount"
  668.     If hypercount > 0 And hypercount < 100 Then
  669.         If hypercount/2 = Int(hypercount/2) Then        ;if the value of "hypercount" is EVEN then..
  670.                                                         ;draw these four pictures
  671.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+hypercount,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-hypercount,frame2
  672.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+hypercount,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+hypercount,frame4
  673.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-hypercount,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+hypercount,frame6
  674.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-hypercount,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-hypercount,frame8
  675.  
  676.         Else                                            ;otherwise, if the value of "hypercount" is ODD, then..
  677.                                                         ;draw these four pictures..
  678.                                                         ;this ODD/EVEN swapping results in our "flickery" effect, but you
  679.                                                         ;can see the distinct 4 pictures if you PAUSE the game in the middle of a jump!
  680.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-(1.4*hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,frame7
  681.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+(1.4*hypercount),frame5
  682.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+(1.4*hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,frame3
  683.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-(1.4*hypercount),frame1
  684.         End If
  685.     ElseIf hypercount >= 100 And hypercount < 200 Then    ;between 0 and 100, the 8 "ships" move outwards from the middle..
  686.                                                         ;after that, they converge back to the centre, using exactly the same code, but "200 - hypercount"
  687.                                                         ;instead of "hypercount". It's a cheap effect that didn't cost me any more Paint Shop Pro time
  688.                                                         ;and it looks quite cool! :)
  689.         If hypercount/2 = Int(hypercount/2) Then
  690.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+(200-hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-(200-hypercount),frame2
  691.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+(200-hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+(200-hypercount),frame4
  692.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-(200-hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+(200-hypercount),frame6
  693.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-(200-hypercount),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-(200-hypercount),frame8
  694.         Else
  695.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2-(1.4*(200-hypercount)),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,frame7
  696.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2+(1.4*(200-hypercount)),frame5
  697.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2+(1.4*(200-hypercount)),(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,frame3
  698.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2-(1.4*(200-hypercount)),frame1
  699.         End If
  700.  
  701.     Else            ;if, on the other hand, we're not mid-hyperjump, then we'll just be drawing the normal player frames..
  702.     
  703.         ;checks to see that the angle we want to draw the frame for is 0 to 71 (as 360 degrees is the same as 0 degrees!)
  704.         game_player_frame = PLAYER_ANGLE/5
  705.         If game_player_frame = 72 Then
  706.             game_player_frame = 0
  707.         End If
  708.         
  709.         If cloakon = 0 Then        ;if the "cloaking device" is off, then draw the player every screen update..
  710.             DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,game_player_frame
  711.  
  712.         Else                    ;if the "cloaking device" is on, only draw the player when the "cloakon" number is EVEN..
  713.                                 ;this is our flickering effect used again..
  714.             If cloakon/2 = Int(cloakon/2) Then
  715.                 DrawImage game_player,(SCREEN_WIDTH/2)-ImageWidth(game_player)/2,(SCREEN_HEIGHT/2)-ImageHeight(game_player)/2,game_player_frame
  716.             End If
  717.         End If
  718.     End If
  719.     
  720.     ;As we said before, the foremost pictures/displayed objects are drawn last in our Video collage.
  721.     Color 0,128,0
  722.     Text SCREEN_WIDTH-210,220,"SCORE: " + PLAYER_SCORE
  723.     Text SCREEN_WIDTH-210,240,"HISCR: " + HI_SCORE
  724.     Text SCREEN_WIDTH-210,260,"BOOST: " + Int(PLAYER_BOOSTERS)
  725.     Text SCREEN_WIDTH-210,280,"CLOAK: " + Int(PLAYER_CLOAK)
  726.     Text SCREEN_WIDTH-210,300,"JUMPS: " + PLAYER_JUMPS
  727.     Line SCREEN_WIDTH-210,3,SCREEN_WIDTH-10,3
  728.     Line SCREEN_WIDTH-210,213,SCREEN_WIDTH-10,213
  729.     Line SCREEN_WIDTH-210,3,SCREEN_WIDTH-210,213
  730.     Line SCREEN_WIDTH-10,3,SCREEN_WIDTH-10,213
  731.         ;notice that by using a calculated x coordinate "SCREEN_WIDTH - value" in conjunction with a fixed
  732.         ;y coordinate, we will have the HUD images at the same distance from the top right of the screen
  733.         ;in any Graphics resolution we choose -- PLUS I've made the radar border GREEN using the color command
  734.         
  735.     Color 255,0,255
  736.     
  737.     ;this next bit of code draws the coloured dots on the radar
  738.     ;by using their game map coordinates, at a ratio to the size of the radar box graphic
  739.     For icon.icons=Each icons
  740.         ;this draws each of the icons
  741.         DrawImage game_icon_dot,((SCREEN_WIDTH-211)+icon\x/(GAME_AREA_X/200)),((9)+icon\y/(GAME_AREA_Y/200))
  742.     Next
  743.     
  744.     ;this next bit draws the player's green dot on the radar
  745.     If hypercount = 0 And cloakon=0 Then    ;if both the "hypercount" and "cloakon" features are inactive (i.e.: normal play)
  746.         ;then permanently draw the player's radar dot
  747.         DrawImage game_player_dot,((SCREEN_WIDTH-211)+PLAYER_X/(GAME_AREA_X/200)),((9)+PLAYER_Y/(GAME_AREA_Y/200))
  748.  
  749.     ElseIf hypercount = 0 And (cloakon/2 = Int(cloakon/2)) Then
  750.         ;otherwise, if the cloakon value is EVEN, draw the dot (flickery effect again)
  751.         ;but if the hypercount value isn't 0 (we're in the middle of a hyperjump) then don't do this..
  752.         ;.. consequently, even though the player's position moves on the radar map during a hyperjump,
  753.         ;and it affects the enemies, don't show this to the user!
  754.         DrawImage game_player_dot,((SCREEN_WIDTH-211)+PLAYER_X/(GAME_AREA_X/200)),((9)+PLAYER_Y/(GAME_AREA_Y/200))
  755.     End If
  756.  
  757.     ;if the game is paused (FLAG_PAUSE = 1) then draw the image when "game_pause_stat" = 1
  758.     ;this gives us our flash on-off effect as used earlier in "menu_draw_update()"
  759.     
  760.     If FLAG_PAUSE = 1 And game_pause_stat = 1 Then
  761.         DrawImage game_paused,SCREEN_WIDTH/2-ImageWidth(game_paused)/2,SCREEN_HEIGHT-((SCREEN_HEIGHT-350)/2+ImageHeight(game_paused)/2)
  762.     End If
  763.     
  764.     ;the following text will only be printed on the screen while the "FLAG_DEBUG" variable is set to 1 (F1, as I programmed it, on the main menu!)
  765.     If FLAG_DEBUG = 1 Then
  766.         ;the TEXT command writes a STRING of text onto the screen at the given coordinates in the currently set font
  767.         ;as I haven't used the LoadFont or SetFont commands, this will just be Blitz' default font.
  768.  
  769.         Color 255,255,255                                    ;just in case, set the colo(u)r of the text to WHITE (255, 255, 255)
  770.         Text 0,0,"PLAYER ANGLE = " + PLAYER_ANGLE                ;"Write the string 'PLAYER ANGLE = ' followed by the number held in PLAYER_ANGLE"
  771.         Text 0,20,"PLAYER SPEED = " + PLAYER_SPEED
  772.         Text 0,40,PLAYER_ANGLE + " / 5 = " + PLAYER_ANGLE/5
  773.         Text 0,60,"SHIPFRAME = " + game_player_frame
  774.         Text 0,80,"CO-ORDS = " + Int(PLAYER_X)
  775.         Text 140,80," , " 
  776.         Text 160,80,Int(PLAYER_Y)
  777.         Text 0,120, "SCORE = " + PLAYER_SCORE
  778.  
  779.         ;this debug code counts how many bullets are "active" in the array (their 'style' - bullets(i,4) is not 0
  780.         ;this was useful for deciding how big the array needed to be for the game, i.e.: how many bullets array
  781.         ;containers would be in use at any one time.
  782.         ;in reality, during the game, this value rarely gets above 100 active bullets,
  783.         ;but I kept the "available" bullets (bulletnum) at 500 anyway.
  784.         
  785.         ;if you needed better performance, then decreasing the value of "bulletnum" might increase the speed of the program!
  786.         bulletcount = 0
  787.         For i = 0 To bulletnum-1
  788.             If bullets(i,4) > 0 Then
  789.                 bulletcount = bulletcount + 1
  790.             End If
  791.         Next
  792.         Text 0,160, "BULLETS = " + bulletcount
  793.     End If
  794.     
  795.     ;just like in "menu_draw_update()", the user can press a key which just makes the value of "FLAG_SCREENSAVE" equal 1.
  796.     ;when the code gets to here, it saves out the named Buffer as a BMP picture.
  797.     If FLAG_SAVESCREEN=1 Then
  798.         SaveBuffer (BackBuffer(),"CRGameScreen.bmp")
  799.         FLAG_SAVESCREEN = 0
  800.     End If 
  801.     
  802.     Flip                    ;as before in "menu_draw_update()", FLIP everything we've just drawn on the backbuffer and show it on the frontbuffer, i.e.: your monitor!!
  803. End Function
  804.  
  805. ;a little function which randomizes the x and y coordinates of each version of the "stars" Type, plus it's "depth" property
  806. Function game_stars_randomize()
  807.     For star.stars=Each stars
  808.         star\x=Rnd(-5,SCREEN_WIDTH)            ;create random x and y positions for all the stars
  809.         star\y=Rnd(-5,SCREEN_HEIGHT)
  810.         star\depth=Rnd(1,5)                    ;the depth of the stars results in our sexy parallex effect
  811.     Next
  812. End Function
  813.  
  814. ;an even littler function which just gives us random x and y coordinates for the player.
  815. Function game_player_randomize()
  816.     PLAYER_X = Rand(0,GAME_AREA_X)
  817.     PLAYER_Y = Rand(0,GAME_AREA_Y)
  818. End Function
  819.  
  820.  
  821. ;This is the last function and it's MARVELLOUS! :)
  822. ;This is the type of function that you should proactively *try* to write, because they're incredibly simple, yet incredibly effective
  823. ;and they impress the girls, I can tell you... Um.. No.. That's a lie..
  824.  
  825. ;anyway the beauty of this function is that when you call it in the code above, you "feed" it some parameters.
  826. ;this one is expecting an X Coordinate, a Y Coordinate, an Angle value, a Speed value and a Style value.
  827. ;it doesn't care who or what they refer to, it just knows that it wants 5 numbers to work with.
  828.  
  829. ;So, when a player requires two bullets to be made, I just give it "PLAYER_X, PLAYER_Y, PLAYER_ANGLE,
  830. ;PLAYER_SPEED and 1 (which just makes sure the correct bullet AnimImage is used!)
  831.  
  832. ;When an enemy needs a bullet, I just give it "Enemy X, Enemy Y, Enemy Angle, Enemy Speed, 2"
  833.  
  834. ;the createbullet() function does the rest and "produces" 2 bullets on the screen, starting at the end of the calling ship's laser.. BUT THAT'S ALL..
  835. ;After the bullet has been created, its "life" is calculated in another part of the code (it's x and y coordinates are altered based on the original angle and speed
  836. ;calculated in this function..) Enjoy
  837.  
  838. Function createbullet(x,y,angle,speed,style) ;creates 2 bullets starting on the end of a ship's lasers.
  839.  
  840.     ;there are "bulletnum" containers available in the "bullets()" array.
  841.     ;if we've reached the maximum number of bullets, then the very first
  842.     ;'bullet' will be overwritten with this new bullet. 
  843.     ;We do this by wrapping "nextbullet" back to 0, when it reaches bulletnum
  844.     If nextbullet = bulletnum-1 Then
  845.         nextbullet = 0
  846.     End If
  847.     
  848.     ;we want to create a bullet for the RIGHT laser of a ship
  849.     ;by messing with the angleoffset value during debugging, I was able to come up with the
  850.     ;correct values that looked right on screen (30 for this angle and 28 for the next calculation)
  851.     angleoffset = angle - 30
  852.     bullets(nextbullet,0) = x + 28*Cos(angleoffset)        ;this sets the x and y pixel offset from the ship's game coordinates
  853.     bullets(nextbullet,1) = y + 28*Sin(angleoffset)        ;in this case 28*Cos/Sin of the angle offset
  854.  
  855.     ;these next bits are just setting the origin of the bullets, including it's start position, speed and angle
  856.     ;this is so the bullets can fly independently of the PLAYER's ship's Angle and speed (unlike everything else in the game)
  857.     bullets(nextbullet,2) = angle
  858.     If speed <= 0 Then                        ;this bit essentially stops the player catching up to his bullets, or bullets flying backwards
  859.         bullets(nextbullet,3) = 25            ;if the ship is still, or moving backwards, then a bullet fires off at a speed of 25
  860.     Else
  861.         bullets(nextbullet,3) = speed + 25    ;otherwise, if a ship is moving forwards, then the bullet flys off at a speed of 25, PLUS the ship's speed
  862.     End If
  863.  
  864.     bullets(nextbullet,4) = style                    ;used to decide which bullet AnimImage should be used
  865.     bullets(nextbullet,5) = 0                            ;used to keep track of the frame of animation a bullet is on
  866.     bullets(nextbullet,6) = bullets(nextbullet,0)        ;used to know where a bullet began it's life in x and y coordinates
  867.     bullets(nextbullet,7) = bullets(nextbullet,1)
  868.     nextbullet = nextbullet+1                        ;we've successfully created a bullet (whose 'life' from now on will be calculated back
  869.                                                     ;in "game_loop_update()", so now we move the "nextbullet" value on by 1
  870.                                                     ;ready for creation of the next bullet!
  871.  
  872.  
  873.  
  874.     If nextbullet = bulletnum-1 Then                    ;exactly the same process, but with a 120 degree offset for the left hand laser
  875.         nextbullet = 0
  876.     End If
  877.     angleoffset = angle - 150
  878.     bullets(nextbullet,0) = x + 28*Cos(angleoffset)
  879.     bullets(nextbullet,1) = y + 28*Sin(angleoffset)
  880.     bullets(nextbullet,2) = angle
  881.     If speed <= 0 Then
  882.         bullets(nextbullet,3) = 25
  883.     Else
  884.         bullets(nextbullet,3) = speed + 25
  885.     End If
  886.     bullets(nextbullet,4) = style
  887.     bullets(nextbullet,5) = 0
  888.     bullets(nextbullet,6) = bullets(nextbullet,0)
  889.     bullets(nextbullet,7) = bullets(nextbullet,1)
  890.     nextbullet = nextbullet+1
  891. End Function